package cn.rui.service;

import cn.rui.mapper.AdminMapper;
import cn.rui.mapper.PermMapper;
import cn.rui.pojo.Admins;
import cn.rui.pojo.Menu;
import cn.rui.pojo.Permissions;
import cn.rui.utils.SaltUtils;
import cn.rui.vo.PermAdminQuery;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Flush;
import org.apache.ibatis.annotations.Options;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 徽州大都督
 * @date 2020/8/12
 */
@Service
public class AdminService {

    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private PermMapper permMapper;
    @Autowired
    private MenuService menuService;

    public int register(Admins admins) {
        //处理密码md5+salt+hash散列
        //生成随机盐
        String salt = SaltUtils.getSalt (8);
        admins.setSalt (salt);
        Md5Hash md5Hash = new Md5Hash (admins.getAdminPassword (), salt, 1024);
        admins.setAdminPassword (md5Hash.toHex ());
        if (admins.getSexStr ().equals ("男")) {
            admins.setAdminSex (1);
        } else if (admins.getSexStr ().equals ("女")) {
            admins.setAdminSex (0);
        } else {
            admins.setAdminSex (2);
        }

        admins.setLoginTime (new Date ());

        QueryWrapper<Permissions> wrapper = new QueryWrapper<> ();
        Permissions a_name = permMapper.selectOne (wrapper.eq ("p_name", admins.getAdminName ()));
        admins.setPid (a_name.getPid ());
        int insert = adminMapper.insert (admins);

        return insert;
    }

    /**
     * 根据用户名查询
     *
     * @param username
     * @return
     */
    public Admins findByName(String username) {
        QueryWrapper<Admins> wrapper = new QueryWrapper<> ();
        Admins admins = adminMapper.selectOne (wrapper.eq ("admin_username", username));

        if (!ObjectUtils.isEmpty (admins)){
            Permissions permissions = permMapper.selectById (admins.getPid ());
            admins.setPermissions (permissions);
        }


        return admins;

    }

    /**
     * 登陆成功修改登陆次数
     *
     * @param adminUsername
     */
    public Admins updateCounts(String adminUsername) {
        Admins admins = findByName (adminUsername);
        admins.setLoginCount (admins.getLoginCount () + 1);
        admins.setLoginTime (new Date ());
        adminMapper.updateById (admins);
        List<Menu> menuList = menuService.findByStatus ();

        String str="";
        for (Menu menu : menuList) {
            str=str+menu.getMenuName ()+",";
        }
        admins.setMenuStr (Arrays.asList (str.substring (0, str.lastIndexOf (","))));

        //System.out.println (admins.getMenuStr ());

        return admins;
    }

    /**
     * 分页查询
     *
     * @param
     * @param page
     * @param size
     * @return
     */
    public List<Admins> findByPage(int page, int size, PermAdminQuery permAdminQuery) {


        Page<Admins> page1 = new Page<> (page, size);

        List<Admins> list = adminMapper.selectList (null);

        List<Permissions> permissionsList = null;
        if (CollectionUtils.isEmpty ((List<Permissions>) redisTemplate.opsForValue ().get ("permList"))) {
            permissionsList = permMapper.selectList (null);
            redisTemplate.opsForValue ().set ("permList", permissionsList, 30, TimeUnit.DAYS);
        } else {
            permissionsList = (List<Permissions>) redisTemplate.opsForValue ().get ("permList");
        }

        QueryWrapper<Admins> wrapper2 = new QueryWrapper<> ();

        if (permAdminQuery.getPid () != null) {
            wrapper2.eq ("pid", permAdminQuery.getPid ());
        }

        if (!StringUtils.isEmpty (permAdminQuery.getAdminUsername ()) && (permAdminQuery.getAdminUsername ()).matches ("[a-zA-Z0-9]+")) {
            wrapper2.like ("admin_username", permAdminQuery.getAdminUsername ());
        }

        IPage<Admins> adminsIPage = adminMapper.selectPage (page1, wrapper2);

        //long total = adminsIPage.getTotal ();
        List<Admins> adminsList = adminsIPage.getRecords ();



        if (CollectionUtils.isEmpty (adminsList)) {
            List<Admins> adminsList2=new ArrayList<> ();

            Admins admins = new Admins ();

            //Permissions one = permMapper.selectOne (wrapper.eq ("pid", admins.getPid ()));
            admins.setTotal (0L);
            admins.setPermList (permissionsList);
            //admins.setPermissions (one);
            adminsList2.add (admins);
            return adminsList2;

        } else {
            for (Admins admins : adminsList) {
                QueryWrapper<Permissions> wrapper = new QueryWrapper<> ();
                Permissions one = permMapper.selectOne (wrapper.eq ("pid", admins.getPid ()));
                admins.setPermissions (one);
                admins.setTotal ((long) list.size ());
                admins.setPermList (permissionsList);
            }
        }


        return adminsList;
    }

    /**
     * 启用/封禁管理员账户
     * @param aid
     */
    public void updateStatus(Integer aid) {
        Admins admins = adminMapper.selectById (aid);
        if (admins.getAStatus ()==1){
            admins.setAStatus (0);
            adminMapper.updateById (admins);
        }else {
            admins.setAStatus (1);
            adminMapper.updateById (admins);
        }
    }

    /**
     * 删除管理员
     * @param aid
     */
    public void delAdmin(Integer aid) {
        adminMapper.deleteById (aid);
    }

    /**
     * 根据pid查询用户
     * @param pid
     */
    public List<Admins> findByPid(Integer pid) {
        QueryWrapper<Admins> wrapper =new QueryWrapper<> ();
       return adminMapper.selectList (wrapper.eq ("pid",pid));
    }

    /**
     * 给管理员添加权限
     * @param admin
     * @param per
     */
    public void addPerm(List<Integer> admin, List<String> per) {
        for (Integer aid : admin) {
            Admins admins = adminMapper.selectById (aid);
            admins.setPerStr (per.toString ());
            adminMapper.updateById (admins);
        }
    }

    /**
     * 管理员修改登陆密码
     * @param username
     * @param password
     * @return
     */
    public void updateAdmin(String username, String password) {

        QueryWrapper<Admins> wrapper =new QueryWrapper<> ();
        Admins admins = adminMapper.selectOne (wrapper.eq ("admin_username", username));

        //处理密码md5+salt+hash散列
        //生成随机盐
        String salt = SaltUtils.getSalt (8);
        admins.setSalt (salt);
        admins.setAdminPassword (password);
        Md5Hash md5Hash = new Md5Hash (admins.getAdminPassword (), salt, 1024);
        admins.setAdminPassword (md5Hash.toHex ());

        adminMapper.updateById (admins);


    }

    /**
     * 修改个人信息
     * @param username
     * @param admins
     * @return
     */
    public Admins addUpdate(String username, Admins admins) {

        List<Admins> list = adminMapper.selectList (null);
        for (Admins ad : list) {
            if (ad.getAdminUsername ().equals (admins.getAdminUsername ())){

                Admins a = new Admins ();
                a.setAid (0);
                return a;
            }
        }

        QueryWrapper<Admins> wrapper =new QueryWrapper<> ();

        Admins one = adminMapper.selectOne (wrapper.eq ("admin_username", username));

        one.setAdminUsername (admins.getAdminUsername ());
        one.setAdminSex (admins.getAdminSex ());
        one.setAdminTelephone (admins.getAdminTelephone ());
        one.setAdminEmail (admins.getAdminEmail ());
        one.setDes (admins.getDes ());
        adminMapper.updateById (one);

        return one;
    }
}
